<template>
	<div>
		正方体
		<div id="container"></div>
	</div>
</template>
<script>
	export default {
		data() {
			return {
				scene: null, //场景对象
				camera: null, //相机对象
				renderer: null, //渲染器对象
				mesh: null, //网格模型对象
				controls: null, //创建轨道控制器对象
				angle: 0
			}
		},
		mounted() {
			this.init()
			this.animate()
		},
		methods: {
			init() {
				let container = document.getElementById('container');

				//创建场景对象
				this.scene = new this.$Three.Scene()

				// PerspectiveCamera（透视相机-有好多种，暂且先试用这个）
				// 第一个参数是视野角度:显示器上看到的场景的范围，
				// 第二个参数是长宽比（aspect ratio）：物体的宽/高
				// 三四参数是视锥体的近截面（near）和远截面（far）（这个慢慢查资料吧，哈哈哈） 
				// 创建相机对象
				this.camera = new this.$Three.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 3000)
				// 相机位置
				this.camera.position.set(200, 200, 200)

				// 创建渲染器对象
				this.renderer = new this.$Three.WebGLRenderer()
				// 渲染区域的宽高
				this.renderer.setSize(window.innerWidth / 2, window.innerHeight / 2);
				// 给dom添加渲染器
				container.appendChild(this.renderer.domElement);

				// 创建正方体（BoxGeometry-几何正方体）大小100
				const geometry = new this.$Three.BoxGeometry(100, 100, 100)

				// 创建材质来让它有颜色（MeshBasicMaterial-材质,十六进制的颜色格式,transparent是否透明，透明度)
				// 材质：MeshBasicMaterial：以平面或线框方式来绘制几何体的材质（不受光照影响）
				// 材质：MeshLambertMaterial：漫反射材质（受光照影响） 
				// 这里使用MeshLambertMaterial是为了测试光照，任选其一都可以
				const material = new this.$Three.MeshLambertMaterial({
					color: 0xff0000,
					transparent: true,
					opacity: 0.5
				});

				// 需要一个网格模型对象（Mesh）
				// 网格包含一个几何体以及作用在此几何体上的材质
				// 接收参数（创建的实例，显示的材质）这样实例就已经显示到网格上了
				this.mesh = new this.$Three.Mesh(geometry, material);
				// 设置网格位置
				this.mesh.position.set(0, 0, 0)
				// 把网格添加到场景中
				this.scene.add(this.mesh);

				// 环境光：AmbientLight
				// 点光源：PointLight
				// 可接受两个参数-表示光源颜色和光照强度
				// const light = new this.$Three.PointLight( 0xffffff,400);
				const light = new this.$Three.AmbientLight(0xffffff, 40);
				// 光照位置
				light.position.set(200, 200, 100)
				this.scene.add(light);

				// 创建轨道控制器
				this.controls = new this.$OrbitControls(this.camera, this.renderer.domElement);
				// 监听轨道控制器变化重新渲染
				this.controls.addEventListener('change', this.changRender)
			},


			// 渲染循环”（render loop）或者“动画循环 (animate loop）
			animate() {
				// requestAnimationFrame：相比较定时器，当用户切换到其它的标签页时，它会暂停，因此不会浪费用户宝贵的处理器资源
				requestAnimationFrame(this.animate);

				// 改变网格位置，获得旋转动画
				// this.mesh.rotation.x += 0.01;
				// this.mesh.rotation.y += 0.01;

				// 改变相机的位置.position，三维场景在canvas画布上呈现不同的效果，如果连续改变相机的位置.position，就可以获得一个动画效果。
				// this.camera.position.z += 0.9;

				// 在渲染循环中，改变相机位置，在XOZ平面上绕着y轴圆周运动
				this.angle += 0.01;
				this.camera.position.x = 100 * Math.cos(this.angle);
				this.camera.position.z = 100 * Math.sin(this.angle);
				//  保持相机镜头始终指向坐标原点或其它位置，实现圆周运动
				this.camera.lookAt(0, 0, 0);
				this.changRender()
			},

			// 执行渲染操作
			changRender() {
				this.renderer.render(this.scene, this.camera);
			}
		}
	}
</script>